"""
Case Type   : 资源池化故障模式库
Case Name   : 目录-log共享盘空间不足
Create At   : 2025/05
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、写入大文件，构造log共享盘空间不足
    4、查看业务运行情况
    5、查看集群状态
    6、恢复log共享盘空间
    7、恢复集群状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、构造log盘空间不足成功
    4、业务运行异常
    5、节点状态变为Readonly
    6、log盘空间恢复正常
    7、集群状态恢复正常
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.file_name = 'test_readonly.txt'
        self.vg_conf = os.path.join(macro.DSS_INSTANCE_PATH, 'cfg', 'dss_vg_conf.ini')
        self.vg_name = self.user_node[1].sh(
            f"cat {self.vg_conf} | awk 'NR==2' | awk -F ':' '{{{{print $1}}}}'").result()
        self.log.info(self.vg_name)

        self.log.info('-----获取log共享盘的可用空间-----')
        cmd1 = f"source {macro.DB_ENV_PATH};dsscmd lsvg | awk 'NR==3' | awk '{{{{print$3}}}}'"
        self.log.info(cmd1)
        log_size = self.user_node[1].sh(cmd1).result()
        self.log.info(log_size)

        cmd2 = f"source {macro.DB_ENV_PATH};dsscmd lsvg | awk 'NR==3' | awk '{{{{print$5}}}}'"
        self.log.info(cmd2)
        log_used_size = self.user_node[1].sh(cmd2).result()
        self.log.info(log_used_size)

        self.truncate_size = int(int(log_size.split('.')[0]) * 0.95) - int(log_used_size.split('.')[0])
        self.log.info(self.truncate_size)

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                            f'{macro.TPCC_PATH}',
                                                            tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:写入大文件，构造log共享盘空间不足  expect:写入成功-----'
        self.log.info(text)

        time.sleep(5)
        touch = f'source {macro.DB_ENV_PATH};dsscmd touch -p +{self.vg_name}/{self.file_name}'
        self.log.info(touch)
        touch_execute = self.user_node[1].sh(touch).result()
        self.log.info(touch_execute)
        self.assertIn('Succeed to create file', touch_execute, '创建文件失败')

        truncate = f'source {macro.DB_ENV_PATH};' \
                   f'dsscmd truncate -p +{self.vg_name}/{self.file_name} -l {self.truncate_size}'
        self.log.info(truncate)

        truncate_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], truncate))
        truncate_execute.setDaemon(True)
        truncate_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行异常终止-----'
        self.log.info(text)

        truncate_execute.join()
        ret2 = truncate_execute.get_result()
        self.log.info(ret2)
        self.assertIn('Success to truncate file', ret2, 'log共享盘写入大文件失败')

        tpcc_execute.join()
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('ERROR', ret1, 'tpcc执行成功')

        text = '-----step5:查看集群状态  expect:节点状态变为Readonly-----'
        self.log.info(text)

        time.sleep(30)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Degraded', status, '集群状态正常')
        self.assertIn('Primary ReadOnly', status, '节点状态正常')

    def tearDown(self):
        text = '-----step6:恢复data共享盘size  expect:恢复成功-----'
        self.log.info(text)

        rm = f'source {macro.DB_ENV_PATH};dsscmd rm -p +{self.vg_name}/{self.file_name}'
        self.log.info(rm)
        rm_execute = self.user_node[1].sh(rm).result()
        self.log.info(rm_execute)

        text = '-----step7：恢复集群初始状态，查看集群状态  expect:恢复集群状态成功-----'
        self.log.info(text)

        time.sleep(30)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)

        if 'P Primary' not in status:
            switch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(switch)
            self.assertIn(self.constant.cm_switchover_success_msg, switch, '切换主节点失败')
        self.assertIn('Succeed to remove device', rm_execute, '恢复log共享盘size失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
